/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.icee.myth.manager.channelHandler;

import com.icee.myth.common.messageQueue.ServerMessageQueue;
import com.icee.myth.manager.Manager;
import com.icee.myth.manager.db.DbHandler;
import com.icee.myth.manager.message.serverMessage.builder.ManagerMessageBuilder;
import com.icee.myth.manager.server.DBCharInfo;
import com.icee.myth.manager.server.Server;
import com.icee.myth.manager.web.PlayerInfo;
import com.icee.myth.manager.web.WebServer;
import com.icee.myth.utils.Consts;
import com.icee.myth.utils.LogConsts;
import com.icee.myth.utils.MLogger;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.handler.codec.http.HttpRequest;
import org.jboss.netty.handler.codec.http.QueryStringDecoder;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;

import java.util.Date;
import java.util.List;
import java.util.Map;

import static org.jboss.netty.handler.codec.http.HttpHeaders.is100ContinueExpected;
import static org.jboss.netty.handler.codec.http.HttpResponseStatus.BAD_REQUEST;

/**
 *
 * @author yangyi
 */
public class HttpServerHandlerToWeb extends HttpServerHandler {

	// public DbHandler dbHandler;

	public HttpServerHandlerToWeb() {
		// dbHandler = new DbHandler(Manager.INSTANCE.dbHost,
		// Manager.INSTANCE.dbName);
	}

	@Override
	public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e)
			throws Exception {
		// 判定浏览器ip是否合法
		// Channel channel = e.getChannel();
		// String browserIP = channel.getRemoteAddress().toString();
		// browserIP = browserIP.substring(1, browserIP.indexOf(":"));
		// if (Manager.INSTANCE.isTrustedBrowser(browserIP)) {
		// MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_ERROR, "Browser[" +
		// browserIP + "] connected.");
		// } else {
		// channel.close();
		// MLogger.getlogger().debuglog(LogConsts.LOGLEVEL_ERROR, "Browser[" +
		// browserIP + "] not trusted.");
		// }
	}

	@Override
	public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e)
			throws Exception {
		super.channelClosed(ctx, e);
		// dbHandler.close();
	}

	@Override
	public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
			throws Exception {
		if (e.getChannel().isOpen()) {
			HttpRequest request = (HttpRequest) e.getMessage();

			if (is100ContinueExpected(request)) {
				sendError(ctx, BAD_REQUEST);
				return;
			}

			String uri = request.getUri();
			MLogger.getlogger().debuglog(
					LogConsts.LOGLEVEL_DEBUG,
					"clientIP:" + e.getChannel().getRemoteAddress().toString()
							+ " Uri " + uri);
			try {
				if (uri.equals("/session/get")) {
					getSession(e.getChannel(), request);
				} else if (uri.equals("/session/check")) {
					checkSession(e.getChannel(), request);
				} else if (uri.equals("/services")) {
					// 得到服务器列表JSON串
					services(e.getChannel(), request);
				} else if (uri.equals("/rank/level")) {
					rankByLevel(e.getChannel(), request);
				} else if (uri.equals("/service")) {
					// 玩家已登录，使用存储过程查询出游戏服务器列表。
					service(e.getChannel(), request);
				} else if (uri.equals("/logout")) {
					logout(e.getChannel(), request);
				} else if (uri.equals("/getchar")) {
					getChar(e.getChannel(), request);
				} else if (uri.equals("/billnotify")) {
					billNotify(e.getChannel(), request);
				}
			} catch (Exception exp) {
				exp.printStackTrace();
			}
		}
	}

	private void getSession(Channel channel, HttpRequest request) {
		QueryStringDecoder queryStringDecoder = new QueryStringDecoder("?"
				+ request.getContent().toString(
						org.jboss.netty.util.CharsetUtil.UTF_8));
		Map<String, List<String>> queryMap = queryStringDecoder.getParameters();
		String passport = null;
		Integer serverId = null;
		Integer auth = null;

		List<String> passportList = queryMap.get("passport");
		if (passportList != null && passportList.size() == 1) {
			passport = passportList.get(0);
		}
		List<String> serverIdList = queryMap.get("serverid");
		if (serverIdList != null && serverIdList.size() == 1) {
			serverId = Integer.parseInt(serverIdList.get(0));
		}
		List<String> authList = queryMap.get("auth");
		if (authList != null && authList.size() == 1) {
			auth = Integer.parseInt(authList.get(0));
		}

		Server server = null;
		if (serverId != null) {
			server = Manager.INSTANCE.getServer((int) (long) serverId);
		}
		if (passport != null && serverId != null && server != null
				&& auth != null) {
			DbHandler dbHandler = new DbHandler(Manager.INSTANCE.dbHost,
					Manager.INSTANCE.dbName);

			WebServer webServer = Manager.INSTANCE.webServer;
			PlayerInfo info = webServer.getPlayerInfoByPassport(passport);
			if (info == null) {
				info = webServer.newPlayerInfo(dbHandler, passport);
			}
			if (info != null) {
				long now = System.currentTimeMillis();
				if (info.forbiddenEndLoginTime < now / 1000) {
					if (auth == 1) {
						info.auth = true;
					} else {
						info.auth = false;
					}
					// info.clientIp = clientIp;
					MLogger.getlogger().debuglog(
							LogConsts.LOGLEVEL_INFO,
							"[" + new Date(System.currentTimeMillis())
									+ "] Passport[" + passport
									+ "] Get session [" + info.sessionId
									+ "] for client[" + info.clientIp + "].");
					writeResponse(
							request,
							channel,
							"text/html; charset=UTF-8",
							"{\"result\":" + 0 + ",\"sessionid\":\""
									+ info.sessionId + "\",\"expiretime\":"
									+ info.time + ",\"serverip\":\""
									+ server.serverConfig.externalHost
									+ "\",\"serverport\":"
									+ server.serverConfig.externalPort
									+ ",\"serverstatus\":\""
									+ server.getServerStatus() + "\"}", null);
				} else {
					writeResponse(request, channel, "text/html; charset=UTF-8",
							"{\"result\":"
									+ Consts.GETSESSION_ERR_FORBIDDEN_LOGIN
									+ ",\"error\":\"forbidden login\"}", null);
				}
			} else {
				writeResponse(request, channel, "text/html; charset=UTF-8",
						"{\"result\":" + Consts.GETSESSION_ERR_SERVER
								+ ",\"error\":\"system error\"}", null);
			}

			// first login log
			dbHandler.firstlogin(passport, (int) (long) serverId,
					getRemoteIP(channel));

			dbHandler.close();
		} else {
			writeResponse(request, channel, "text/html; charset=UTF-8",
					"{\"result\":" + Consts.PARAMETER_SERVER
							+ ",\"error\":\"parameter error\"}", null);
		}
	}

	// 服务器连接用来校验sessionid
	private void checkSession(Channel channel, HttpRequest request) {
		String contentStr = request.getContent().toString(
				org.jboss.netty.util.CharsetUtil.UTF_8);
		JSONObject jobj = (JSONObject) JSONValue.parse(contentStr);
		if (jobj != null) {
			String sessionid = (String) jobj.get("sessionId");
			// String clientIp = (String) jobj.get("clientIp");
			if (sessionid != null /* && clientIp != null */) {
				WebServer webServer = Manager.INSTANCE.webServer;
				PlayerInfo info = webServer.GetPlayerInfoBySessinoId(sessionid);
				if (info != null
						&& info.forbiddenEndLoginTime < System
								.currentTimeMillis() / 1000) {
					writeResponse(request, channel, "text/html; charset=UTF-8",
							"{\"result\":" + 0 + ",\"id\":" + info.cid
									+ ",\"passport\":\""
									+ info.thirdPartyUserId
									+ "\",\"forbiddenendtalktime\":"
									+ info.forbiddenEndTalkTime
									+ ",\"forbiddenendlogintime\":"
									+ info.forbiddenEndLoginTime + ",\"auth\":"
									+ info.auth + "}", null);
				} else {
					writeResponse(request, channel, "text/html; charset=UTF-8",
							"{\"result\":" + Consts.CHECKSESSION_ERR_SESSION
									+ ",\"error\":\"sessionid error\"}", null);
				}
			} else {
				writeResponse(request, channel, "text/html; charset=UTF-8",
						"{\"result\":" + Consts.PARAMETER_SERVER
								+ ",\"error\":\"parameter error\"}", null);
			}
		} else {
			writeResponse(request, channel, "text/html; charset=UTF-8",
					"{\"result\":" + Consts.PARAMETER_SERVER
							+ ",\"error\":\"paramater not json format\"}", null);
		}
	}

	/** 得到服务器列表JSON串 */
	private void services(Channel channel, HttpRequest request) {
		String content = "{\"result\":0,\"services\":[";
		// 拼接服务器列表JSON串
		for (Server server : Manager.INSTANCE.getServers().values()) {
			content += "{\"id\":" + server.getId() + ",\"name\":\""
					+ server.getName() + "\",\"status\":\""
					+ server.getServerStatus() + "\"},";
		}

		content = content.substring(0, content.length() - 1);
		content += "]}";
		writeResponse(request, channel, "text/html; charset=UTF-8", content,
				null);
	}

	private void rankByLevel(Channel channel, HttpRequest request) {
		QueryStringDecoder queryStringDecoder = new QueryStringDecoder("?"
				+ request.getContent().toString(
						org.jboss.netty.util.CharsetUtil.UTF_8));
		Map<String, List<String>> queryMap = queryStringDecoder.getParameters();
		Integer serverId = null;

		List<String> serverIdList = queryMap.get("serverid");
		if (serverIdList != null && serverIdList.size() == 1) {
			serverId = Integer.parseInt(serverIdList.get(0));
		}
		if (serverId != null) {
			Server server = Manager.INSTANCE.getServer(serverId);
			if (server != null) {
				StringBuffer content = new StringBuffer();
				if (server.getTop10ByLevel(content)) {
					writeResponse(request, channel, "text/html; charset=UTF-8",
							"{\"result\":0,\"rank\":" + content + "}", null);
				} else {
					writeResponse(request, channel, "text/html; charset=UTF-8",
							"{\"result\":" + Consts.ERR_SERVER
									+ ",\"error\":\"system error\"}", null);
				}
			} else {
				writeResponse(request, channel, "text/html; charset=UTF-8",
						"{\"result\":" + Consts.PARAMETER_SERVER
								+ ",\"error\":\"parameter error\"}", null);
			}
		} else {
			writeResponse(request, channel, "text/html; charset=UTF-8",
					"{\"result\":" + Consts.PARAMETER_SERVER
							+ ",\"error\":\"parameter error\"}", null);
		}
	}

	/** 玩家已登录，使用存储过程查询出游戏服务器列表。 */
	private void service(Channel channel, HttpRequest request) {
		QueryStringDecoder queryStringDecoder = new QueryStringDecoder("?"
				+ request.getContent().toString(
						org.jboss.netty.util.CharsetUtil.UTF_8));
		Map<String, List<String>> queryMap = queryStringDecoder.getParameters();
		String passport = null;

		List<String> passportList = queryMap.get("passport");
		if (passportList != null && passportList.size() == 1) {
			passport = passportList.get(0);
		}

		if (passport != null) {
			// int thirdPartyId = 0;
			DbHandler dbHandler = new DbHandler(Manager.INSTANCE.dbHost,
					Manager.INSTANCE.dbName);
			// 玩家已登录，使用存储过程查询出游戏服务器列表。
			List<Integer> servers = dbHandler.getServersHasLogin(passport);
			dbHandler.close();
			if (servers != null) {
				// 拼接出游戏服务器列表JSON串
				StringBuilder content = new StringBuilder(
						"{\"result\":0,\"services\":[");
				for (int i = 0; i < servers.size(); i++) {
					int serverId = servers.get(i);
					if (i != 0) {
						content.append(",");
					}
					content.append(serverId);
				}
				content.append("]}");
				writeResponse(request, channel, "text/html; charset=UTF-8",
						content.toString(), null);
			} else {
				writeResponse(request, channel, "text/html; charset=UTF-8",
						"{\"result\":" + Consts.ERR_SERVER
								+ ",\"error\":\"system error\"}", null);
			}
		} else {
			writeResponse(request, channel, "text/html; charset=UTF-8",
					"{\"result\":" + Consts.PARAMETER_SERVER
							+ ",\"error\":\"parameter error\"}", null);
		}

	}

	private void getChar(Channel channel, HttpRequest request) {
		QueryStringDecoder queryStringDecoder = new QueryStringDecoder("?"
				+ request.getContent().toString(
						org.jboss.netty.util.CharsetUtil.UTF_8));
		Map<String, List<String>> queryMap = queryStringDecoder.getParameters();
		String passport = null;
		Integer serverId = null;

		List<String> passportList = queryMap.get("passport");
		if (passportList != null && passportList.size() == 1) {
			passport = passportList.get(0);
		}
		List<String> serverList = queryMap.get("serverid");
		if (serverList != null && serverList.size() == 1) {
			serverId = Integer.parseInt(serverList.get(0));
		}
		Server server = Manager.INSTANCE.getServer(serverId);
		if (passport != null && server != null) {
			PlayerInfo info = Manager.INSTANCE.webServer
					.getPlayerInfoByPassport(passport);
			if (info == null) {
				DbHandler dbHandler = new DbHandler(Manager.INSTANCE.dbHost,
						Manager.INSTANCE.dbName);
				info = dbHandler.getPlayerInfoFromDB(passport);
				dbHandler.close();
			}
			if (info != null) {
				DBCharInfo charInfo = server.getCharInfo(info.cid);
				if (charInfo != null) {
					String content = "{\"result\":0,\"passport\":\"" + passport
							+ "\",\"serverid\":" + serverId + ",\"name\":\""
							+ charInfo.name + "\",\"level\":" + charInfo.level
							+ ",\"sex\":" + charInfo.gender + ",\"job\":"
							+ charInfo.job + "}";
					writeResponse(request, channel, "text/html; charset=UTF-8",
							content.toString(), null);
				} else {
					writeResponse(request, channel, "text/html; charset=UTF-8",
							"{\"result\":" + Consts.ERR_SERVER_NOTHISPLAYER
									+ ",\"error\":\"no such char\"}", null);
				}
			} else {
				writeResponse(request, channel, "text/html; charset=UTF-8",
						"{\"result\":" + Consts.ERR_SERVER_NOTHISPLAYER
								+ ",\"error\":\"no such char\"}", null);
			}

		} else {
			writeResponse(request, channel, "text/html; charset=UTF-8",
					"{\"result\":" + Consts.PARAMETER_SERVER
							+ ",\"error\":\"parameter error\"}", null);
		}

	}

	private void billNotify(Channel channel, HttpRequest request) {
		QueryStringDecoder queryStringDecoder = new QueryStringDecoder("?"
				+ request.getContent().toString(
						org.jboss.netty.util.CharsetUtil.UTF_8));
		Map<String, List<String>> queryMap = queryStringDecoder.getParameters();
		String passport = null;
		Integer serverId = null;

		List<String> passportList = queryMap.get("passport");
		if (passportList != null && passportList.size() == 1) {
			passport = passportList.get(0);
		}
		List<String> serverList = queryMap.get("serverid");
		if (serverList != null && serverList.size() == 1) {
			serverId = Integer.parseInt(serverList.get(0));
		}
		Server server = Manager.INSTANCE.getServer(serverId);
		if (passport != null && server != null) {
			PlayerInfo info = Manager.INSTANCE.webServer
					.getPlayerInfoByPassport(passport);
			if (info == null) {
				DbHandler dbHandler = new DbHandler(Manager.INSTANCE.dbHost,
						Manager.INSTANCE.dbName);
				info = dbHandler.getPlayerInfoFromDB(passport);
				dbHandler.close();
			}
			if (info != null) {
				ServerMessageQueue.queue().offer(
						ManagerMessageBuilder.buildSaveNotifyServerMessage(
								serverId, info.cid));
				writeResponse(request, channel, "text/html; charset=UTF-8",
						"{\"result\":0}", null);
			} else {
				writeResponse(request, channel, "text/html; charset=UTF-8",
						"{\"result\":" + Consts.ERR_SERVER_NOTHISPLAYER
								+ ",\"error\":\"no such char\"}", null);
			}

		} else {
			writeResponse(request, channel, "text/html; charset=UTF-8",
					"{\"result\":" + Consts.PARAMETER_SERVER
							+ ",\"error\":\"parameter error\"}", null);
		}

	}

	private void logout(Channel channel, HttpRequest request) {
		QueryStringDecoder queryStringDecoder = new QueryStringDecoder("?"
				+ request.getContent().toString(
						org.jboss.netty.util.CharsetUtil.UTF_8));
		Map<String, List<String>> queryMap = queryStringDecoder.getParameters();
		String passport = null;

		List<String> passportList = queryMap.get("passport");
		if (passportList != null && passportList.size() == 1) {
			passport = passportList.get(0);
		}
		if (passport != null) {
			WebServer webServer = Manager.INSTANCE.webServer;
			webServer.logout(passport);
			writeResponse(request, channel, "text/html; charset=UTF-8",
					"{\"result\":0}", null);

		} else {
			writeResponse(request, channel, "text/html; charset=UTF-8",
					"{\"result\":" + Consts.ERR_SERVER
							+ ",\"error\":\"system error\"}", null);
		}
	}
}
